isucon13に参加しました
ISUCON13に参加しました!
今回の反省等をまとめ、来年に向けて進んでいきたいと思います。
スコア履歴 #
最終スコアは11,109となりました。
チーム名(一人ですが)はkataokatsukiです。
体制・事前準備等 #
言語はRubyを使用しました。
メンバーについては、自分1人で挑戦をしました。
事前準備については1ヶ月前ほどから、
去年の時直しとしてISUCON12にちょくちょく取り組んでいました。
とりあえず予選突破しました、やったね pic.twitter.com/ifJEJgYNeN
— Kataoka Katsuki (@kataokatsuki) November 21, 2023
目標 #
ISUCONは以前に出た際には
- Failでスコア無し
- ベンチがFailになってる理由が分からず、デバッグに時間取られて何も出来ずにFinish
と散々だったので、 「最低限、今回こそ改善をそれなりにした上でスコアを残そう(FailEndはやめよう)」 と考えてました。
やったこと(ざっくり) #
-
ボトルネックとなっているエンドポイント関連のクエリにインデックスを貼る
-
themeをuserに吸収する(dark_modeカラムをuserに持たせる)
-
iconをFileベースで管理する(iconテーブルを落とす)
userの名前でpublic以下にファイル直接書き込むなどしました。
image = Base64.decode64(req.image) db_transaction do |tx| # tx.xquery('DELETE FROM icons WHERE user_id = ?', user_id) # tx.xquery('INSERT INTO icons (user_id, image) VALUES (?, ?)', user_id, image) # tx.last_id user = tx.xquery('SELECT name FROM users WHERE id = ?', user_id).first username = user[:name] # Delete the old image file if it exists old_image_path = "/home/isucon/webapp/public/images/#{username}.jpg" File.delete(old_image_path) if File.exist?(old_image_path) # Write the new image data to a file File.open(old_image_path, 'wb') do |file| file.write(image) end end
こういう感じ。
そして
get '/api/user/:username/icon'
をNginxで捌く。
良かった点 #
- 最低限の目標は達成した
- パッと眺めた段階でに「あ〜これはこう直せるな」という案が頭に数多く浮かんだ
- 実装まで大体イメージがついた上で進められる箇所が多くあった
- コード眺めた時点で
「ああこれはこうできるな」と思いついたところの一部を実行に移し、完遂した
改善すべき点 #
改善着手までの時間が3h位かかった
手元でISUCON12解いていた時に想定してなかった問題が結構出てきて、「あれえ〜〜」と言いながらポツポツ直してました。
- Mysqlのスロークエリログのパーミッション足りてない
- 各種ライブラリをARMで入れて「アーキテクチャ違う!」
- デプロイスクリプトが各所でコケて、手直しをする
もう全部手動でsshして設定した方が速かったレベルでした。
タスクの優先順位の設定が不味かった
alpとpt-query-digestで「あーここ遅いな」となっている箇所のみインデックスを貼って、次の作業に進みました。
しかし一通りちゃんと貼っといた方が、楽に早く点数上げられたなという感じです。
変更を加えるのを恐れすぎた
以前の経験で、「何や分からんがベンチが失敗し続ける」状況になったことにより
ものすごく小さく変更加えてました。
安全方面に倒したはいいんですが、もっとガンガン進んで良かったかなーと思います。
去年に比べて開発力がかなり伸びてるのを実感したと共に、
自分の力を適切に理解して変更の粒度をコントロールできていれば、
かなりスコア伸ばせたんじゃないかなと思います。
各種ミドルウェア設定ファイルの設定の理解が不足していた
Mysqlのslow-query-logのパーミッションの話もそうですが、 Nginxのroot範囲外に置いたファイルに対してtry-filesしてました。
「ああ、そうだそうだ」と気づくのに他の箇所見てたりと時間ロスしてしまいました。
server {
listen 443 ssl;
server_name u.isucon.dev;
server_name *.u.isucon.dev;
ssl_certificate /etc/nginx/tls/_.u.isucon.dev.crt;
ssl_certificate_key /etc/nginx/tls/_.u.isucon.dev.key;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
client_max_body_size 10m;
root /home/isucon/webapp/public/;
location / {
try_files $uri /index.html;
}
location ~ ^/api/user/(.+)/icon$ {
# not allowed
# try_files /home/isuconwebapp/images/$1.jpg /home/isuconwebapp/images/img/NoImage.jpg;
try_files /images/$1.jpg /img/NoImage.jpg;
}
location /api {
proxy_set_header Host $host;
proxy_pass http://localhost:8080;
}
}
観測(等)ツール入れすぎて逆に混乱した
様々なツール入れたんですが、ちゃんと活用していたのは
- htop
- Netdata
- Sentry
- alp
- pt-query-digest
位でした。 (これで確認できる範囲で修正終わったら、プロファイラをしっかり見ていこうと考えていました)
他にも入れたんですが、入れる手間やら確認する作業やらのコストを考えると あんまり見合わなかった気がします。
「何を・何のために・どう計測するのか?」
を整理する必要があります。
全体的にもっと広い分野で深い知識が必要
ある設定を変更したりする時、「この影響の訴求範囲は?」
等を速く・正しく判断する能力がまだまだ足りないなと感じました。
「あれ、想定外の挙動だな」と考えた際に、
少し遠回りして時間ロスした箇所がしばしばあるなという感じです。
etc ミドルウェアの設定等
「速く」コードを「読む」「書く」能力が足りない
時間があればそれなりの実装まで持っていける気がしてますが、
「速さ」が足りんなと感じました。
「速さ」があれば、
- 学習速度上がる
- アウトプット・フィードバックの回数が増える
等「もっと速くなるための資質が得られやすくなる」気がするので
この辺りは日頃から意識すると覚悟を決めて、負荷をかけていこうと思います。
まとめ #
最低限の目標は達成した上で、具体的な改善項目を整理することが出来て
いい学びの機会となりました。
順当な「力不足(広い意味で)」を感じました。
周りに見本となる方々を参考にして、 日々の業務・趣味で負荷をしっかりかけ、力をつけていこうと思います。
(直接的にisuconに関連はしないかもですが)
各種周辺情報を調べてる時に、CSの基礎的なところで
「あー、思ったよりも知識ボケてるな」と感じた箇所が多く見つかりました。
基礎を再度見直し、一歩ずつ学んで行きたいなと思います。
運営の方々へ #
今年度も素敵な大会をありがとうございました!
自分自身への「去年からどれほど成長しているのか?」の指標として
これ以上無い素晴らしいチャレンジと毎年楽しみにしております。
(例年非常に大変だと思われますが、、)ぜひ来年もよろしくお願い致します、、!!